package com.hope.controller;

import com.hope.domain.dto.LoginFormDTO;
import com.hope.domain.dto.RefreshDTO;
import com.hope.domain.dto.UserDTO;
import com.hope.domain.pojo.Result;
import com.hope.domain.pojo.User;
import com.hope.domain.vo.LoginVO;
import com.hope.mapper.MerchantMapper;
import com.hope.service.UserService;
import com.hope.util.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;

@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private MerchantMapper merchantMapper;

    /**
     * 验证码（验证）
     * @param user
     * @return
     */
    @PostMapping("/send-code")
    public Result sendCode(@Valid @RequestBody LoginFormDTO user) {
        String username = user.getUsername();
        String email = user.getEmail();
        if (RegexUtil.isEmailInvalid(email)) {
            return Result.fail("邮箱格式无效");
        }
        int i = userService.sendCode(username,email);
        if(i==0){
            return Result.fail("邮箱验证码发送失败");
        }else if(i==2){
            return Result.fail("60秒之内已经发送了一条验证码");
        }
        return Result.ok("邮箱验证码发送成功");
    }

    /**
     * 登录 @RequestBody User user
     * @param user
     * @return
     */
    @PostMapping("/login")
    public Result login(@RequestBody @Valid LoginFormDTO user) {
        try {
            System.out.println("user---" + user);

            User userByName = userService.findUserByName(user.getUsername());
            if (userByName == null) {
                return Result.fail("用户名不存在");
            }
            //比较密码
            boolean ok = PwdUtil.match(user.getPassword(), userByName.getPassword());
            if (!ok) {
                return Result.fail("密码有误");
            }
            //token加入
            String accessToken = JwtUtil.createToken(String.valueOf(userByName.getId()));
            String refreshToken = JwtUtil.createRefreshToken(String.valueOf(userByName.getId()));
            //如果是商家
            if (user.getRole() == 1) {
                merchantMapper.existsById(userByName.getId());
                log.info("商家id{}", userByName.getId());
            }
            log.info("用户id{}", userByName.getId());
            LoginVO loginVO = new LoginVO(
                    accessToken,
                    refreshToken,
                    userByName.getId().toString(),  // id
                    userByName.getUsername(),       // username
                    userByName.getNickname(),       // nickname
                    userByName.getAvatar(),         // avatar
                    userByName.getRole(),           // role
                    userByName.getEmail(),          // email
                    userByName.getStatus()          // status
            );
            return Result.ok(loginVO);
        }catch (Exception e){
            e.printStackTrace();
            return Result.fail(e.getMessage());
        }
    }

    /**
     * 注册 @RequestBody User user
     * @param user
     * @return
     */
    @PostMapping("/register")
    public Result register(@RequestBody LoginFormDTO user){
        if (RegexUtil.isEmailInvalid(user.getEmail())) {
            return Result.fail("邮箱格式无效");
        }
        if(user.getCode()==null || user.getCode().equals("")){
            return Result.fail("验证码为空");
        }
        User userByName = userService.findUserByName(user.getUsername());
        if(userByName!=null){
            return Result.fail("用户名已被占用");
        }
        if(userService.verifyCode(user.getUsername(), user.getEmail(), user.getCode()) == 0) {
            return Result.fail("验证码错误");
        }
        //加密
        String encode = PwdUtil.encode(user.getPassword());
        user.setPassword(encode);

        //注册功能点实现
        int registered = userService.register(user);
        if(registered==0){
            return Result.fail("注册有误");
        }
        return Result.ok(registered);
    }


    /**
     * 忘记密码 id email code password
     * @param user
     * @return
     */
    @PostMapping("/forget")
    public Result forget(@RequestBody LoginFormDTO user){
        System.out.println("forgetforgetforget===="+user);
        try {
            if (user.getPassword() == null || !user.getPassword().equals(user.getPasswordConfirm())) {
                return Result.fail("两次输入的密码不一致");
            }
            if (RegexUtil.isEmailInvalid(user.getEmail())) {
                return Result.fail("邮箱格式无效");
            }
            User userByName = userService.findUserByName(user.getUsername());
            if (userByName == null) {
                return Result.fail("用户名不存在");
            }
            if (!userByName.getEmail().equals(user.getEmail())) {
                return Result.fail("邮箱与用户名不匹配");
            }
            if (userService.verifyCode(user.getUsername(), user.getEmail(), user.getCode()) == 0) {
                return Result.fail("验证码错误");
            }
            //加密
            String encode = PwdUtil.encode(user.getPassword());
            System.out.println("encode=" + encode);
            user.setPassword(encode);
            //忘记密码的功能实现
            int login = userService.forget(user);
            if (login == 0) {
                return Result.fail("重置密码错误");
            }
            return Result.ok(login);
        }catch (Exception e){
            return Result.fail(e.getMessage());
        }
    }

    /**
     * 这是给用来展示单独的信息的比如 头像 之类的
     * @param username
     * @return
     */
    @GetMapping("/find-by-username/{username}")
    public Result<UserDTO> findUserByUsername(@PathVariable String username){
        //处理username为空的情况
        if(username==null||username.equals("")){
            return Result.fail("用户id不能为空");
        }
        UserDTO userByUsername = userService.findUserByUsername(username);

        if(userByUsername==null){
            return Result.fail("未查到username为"+username+"用户");
        }
        return Result.ok(userByUsername);
    }

    /**
     * 这是给用来修改单独的信息的比如 年龄,性别,个人所在地,邮箱 之类的
     * @param user
     * @return
     */
    @PostMapping("/edit")//upload
    public Result edit(@RequestBody User user){
        System.out.println("userinfo===="+user);
        if(user==null){
            return Result.fail("前端传输过来的是空的东西");
        }
        if(user.getEmail()==null || user.getEmail().equals("")){
            return Result.fail("邮箱为空");
        }
        int i = userService.edit(user);
        if(i==0)return Result.fail("userService.edit数据库更新失败");
        return Result.ok("数据库更新成功");
    }

    /**
     * 查询 id 的部分用户
     * @param request
     * @return
     */
    @GetMapping("/userinfo")
    public Result getUserInfo(HttpServletRequest request){
        //处理 id 为空的情况
        Long id=Long.parseLong(ThreadLocalUtil.get());
        return userService.getUserInfo(id);
    }

    /**
     * 查询 id 的完整用户信息
     * @param
     * @return
     */
    @GetMapping("/getuserinfo")
    public Result getUserAllInfo(HttpServletRequest request){
        //处理 id 为空的情况
        Long id=Long.parseLong(ThreadLocalUtil.get());
        return userService.getUserAllInfo(id);
    }

    /**
     * 更新 双token
     * @param response
     * @param
     * @return
     */
    @PostMapping("refreshToken")
    public Result refreshToken(@RequestBody RefreshDTO refreshDTO, HttpServletResponse response){
        String refreshToken=refreshDTO.getRefreshToken();
        System.out.println("refreshToken="+refreshToken);
        return userService.refreshToken(refreshToken,response);
    }

    @Autowired
    private AliOSSUtils aliOSSUtils;
    /**
     * 更换头像
     * @param avatar
     * @return
     */
    @PostMapping("/avatar")
    public Result updateAvatar(MultipartFile avatar) throws IOException {
        System.out.println("avatar="+avatar);
        System.out.println("avatar 111");
        String upload = aliOSSUtils.upload(avatar);
        System.out.println("upload"+upload);
        System.out.println(upload);
        System.out.println(2211);

        Long id=Long.parseLong(ThreadLocalUtil.get());
        System.out.println(33111);
        return userService.updateAvatar(upload,id);
    }
}
